package WebBrower_DAO;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.List;



public class SqlDataHelper {

	/**
	 * Đối tượng kết nối CSDL
	 */
	private Connection cn = null;

	/**
	 * Mở kết nối đến CSDL
	 */
	public void OpenConnection() {
		try {

			Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");

			String url = "jdbc:sqlserver://pcchau\\sqlexpress;databaseName=ScanDataInWebsite;user=dtchau;password=dtchau";
			cn = DriverManager.getConnection(url);

		} catch (Exception ex) {
                    String sa = ex.getMessage();
			System.out.println("Lỗi khi mở kết nối: " + ex.getMessage());

		}
	}

	/**
	 * Lấy đối tượng Connection - đối tượng kết nối CSDL
	 * 
	 * @return
	 */
	public Connection getConnection() {
		Connection cnResult = null;
		try {
			cnResult = this.cn;
		} catch (Exception ex) {
			System.out.println("Lỗi khi lấy đối tượng kết nối: "
					+ ex.getMessage());
		}
		return cnResult;
	}

	/**
	 * Đóng kết nối đến CSDL
	 */
	public void CloseConnection() {
		try {
			if (!this.cn.isClosed())
				cn.close();
		} catch (Exception ex) {
			System.out.println("Lỗi khi đóng kết nối: " + ex.getMessage());
		}
	}

	/**
	 * Thực thi các thủ tục trả ra kết quả là table
	 * 
	 * @param storeName
	 *            tên thủ tục
	 * @return
	 */
	public ResultSet excuteQuerySelect(String storeName) {
		ResultSet dataTable = null;
		try {
			if(cn.isClosed())
			{
				this.OpenConnection();
			}
			// chuẩn bị thủ tục cần gọi
			CallableStatement cs = this.cn.prepareCall("{call " + storeName
					+ "}");

			// gọi thực hiện câu truy vấn
			boolean isSuccess = cs.execute();

			// kiểm tra gọi thực hiện câu truy vấn thành công chưa.
			if (isSuccess) {
				// nếu thành công thì lấy ResultSet từ đối tượng truy vấn dữ
				// liệu
				dataTable = cs.getResultSet();
				// while (dataTable.next())
				// {
				// System.out.print(dataTable.getInt("NguoiDungID")) ;

				// }
			}
			// cs.close();
			// dataTable.close();

		} catch (Exception ex) {
			System.out
					.println("Lỗi khi thực thi thủ tục lấy kết quả trả về là 1 bảng (excuteQuerySelect): "
							+ ex.getMessage());
		}
		return dataTable;
	}

	/**
	 * Thực thi thủ tục có tham số truyền vào
	 * 
	 * @param storeName
	 *            tên thủ tục
	 * @param id
	 *            Khóa chính của một bảng
	 * @return
	 */
	public ResultSet excuteQuerySelect(String storeName, ParamDTO param) {
		ResultSet dataTable = null;
		try {
			// chuẩn bị thủ tục cần gọi
			CallableStatement cs = this.cn.prepareCall("{call " + storeName
					+ "(?)}");
			
			cs.setInt(1, (int)param.getGiaTri());
			//cs.setInt(param.getTenThamSo(), (int) param.getGiaTri());

			// gọi thực hiện câu truy vấn
			boolean isSuccess = cs.execute();

			// kiểm tra gọi thực hiện câu truy vấn thành công chưa.
			if (isSuccess) {
				// nếu thành công thì lấy ResultSet từ đối tượng truy vấn dữ
				// liệu
				dataTable = cs.getResultSet();
			}
			// cs.close();
			// dataTable.close();
		} catch (Exception ex) {
			String loi = ex.getMessage();
			String a = loi;
		}
		return dataTable;
	}
	public ResultSet excuteQuerySearch(String storeName, ParamDTO param) {
		ResultSet dataTable = null;
		try {
			// chuẩn bị thủ tục cần gọi
			CallableStatement cs = this.cn.prepareCall("{call " + storeName
					+ "(?)}");
			
			cs.setString(1, (String)param.getGiaTri());
			//cs.setInt(param.getTenThamSo(), (int) param.getGiaTri());

			// gọi thực hiện câu truy vấn
			boolean isSuccess = cs.execute();

			// kiểm tra gọi thực hiện câu truy vấn thành công chưa.
			if (isSuccess) {
				// nếu thành công thì lấy ResultSet từ đối tượng truy vấn dữ
				// liệu
				dataTable = cs.getResultSet();
			}
			// cs.close();
			// dataTable.close();
		} catch (Exception ex) {
			
		}
		return dataTable;
	}
	//
	public ResultSet excuteQuerySearch(String storeName,List<ParamDTO> listParams) {
		ResultSet dataTable = null;
		try {
			String StoreNameResult = getStoreName(storeName, listParams);
			CallableStatement cstmt = cn.prepareCall("{call " + StoreNameResult
					+ "}");

			// gán tham số cho store
			cstmt = setThamSo(cstmt, listParams);

			// gọi thực hiện câu truy vấn
			boolean isSuccess = cstmt.execute();

			// kiểm tra gọi thực hiện câu truy vấn thành công chưa.
			if (isSuccess) {
				// nếu thành công thì lấy ResultSet từ đối tượng truy vấn dữ
				// liệu
				dataTable = cstmt.getResultSet();
			}
			// cs.close();
			// dataTable.close();
		} catch (Exception ex) {
			
		}
		return dataTable;
	}
	/**
	 * Thực thi thủ tục cập nhật
	 * 
	 * @param storeName
	 *            tên thủ tục
	 * @param listParam
	 *            danh sách các tham số truyền vào
	 * @return
	 */
	public boolean excuteNoneQueryUpdate(String storeName,
			List<ParamDTO> listParams) {
		boolean isSuccess = false;
		try {
			String StoreNameResult = getStoreName(storeName, listParams);
			CallableStatement cstmt = cn.prepareCall("{call " + StoreNameResult
					+ "}");

			// gán tham số cho store
			cstmt = setThamSo(cstmt, listParams);

			int iss = cstmt.executeUpdate();
			if (iss == 1) {
				isSuccess = true;
			}
		} catch (Exception ex) {
		}
		return isSuccess;
	}

	/**
	 * Gán tham số vào thủ tục
	 * 
	 * @param cstmt
	 *            đối tượng CallableStatement
	 * @param listParams
	 *            Danh sách các tham số
	 * @return
	 */
	private CallableStatement setThamSo(CallableStatement cstmt,
			List<ParamDTO> listParams) {
		CallableStatement tb = cstmt;
		try {
			// gán tham số vào store
			for (ParamDTO Item : listParams) {
                                    
				switch (Item.getKieuThamSo()) {
				case BooleanType:
					tb.setBoolean(Item.getTenThamSo(),
							(boolean) Item.getGiaTri());
					break;
				case DateType:
					tb.setDate(Item.getTenThamSo(), (Date) Item.getGiaTri());
					break;
				case DoubleType:
					tb.setDouble(Item.getTenThamSo(), (double) Item.getGiaTri());
					break;
				case IntegerType:
					tb.setInt(Item.getTenThamSo(), (int) Item.getGiaTri());
					break;
				case StringType:
					tb.setString(Item.getTenThamSo(), (String) Item.getGiaTri());
					break;
				default:
					break;
				}
			}
		} catch (Exception ex) {
		}
		return tb;
	}

	/**
	 * Lấy tên store có chứa các giá trị cần truyền vào cho thủ tục
	 * 
	 * @param storeName
	 *            tên thủ tục
	 * @param params
	 *            danh sách các tham số
	 * @return
	 */
	private String getStoreName(String storeName, List<ParamDTO> params) {
		String StoreNameResult = storeName;
		try {
			for (int i = 0; i < params.size(); i++) {
				if (i == 0) {
					StoreNameResult += "(?";
				} else if (i == params.size() - 1) {
					StoreNameResult += ",?)";
				} else {
					StoreNameResult += ",?";
				}
			}
		} catch (Exception ex) {
		}
		return StoreNameResult;
	}

	/**
	 * Thực thi thủ tục Insert
	 * 
	 * @param storeName
	 *            tên thủ tục
	 * @param params
	 *            danh sách các tham số
	 * @return
	 */
	public int excuteNonQueryInsert(String storeName, List<ParamDTO> params,
			String storeNameMaxID) {
		int ID = -1;
		try {
			String StoreNameResult = getStoreName(storeName, params);
			CallableStatement cstmt = cn.prepareCall("{call " + StoreNameResult
					+ "}");

			// gán tham số cho store
			cstmt = setThamSo(cstmt, params);

			// thực thi câu truy vấn
			int iss = cstmt.executeUpdate();
			
			if (iss == 1) {
				cstmt.close();
				// thực thi câu truy vấn đã thành công
				// ta lấy ID vừa mới Insert vào
				ResultSet data = excuteQuerySelect(storeNameMaxID);
				if (data.next()) {
					ID = data.getInt("ID");
				}
			}
		} catch (Exception ex) {
			String as = ex.getMessage();
			String dc= as;
		}
		return ID;
	}

	/**
	 * Thực thi thủ tục Xóa
	 * 
	 * @param storeName
	 *            tên thủ tục
	 * @param param
	 *            tham số
	 * @return true: xóa thành công/ false: xóa thất bại
	 */
	public boolean excuteNonQueryDelete(String storeName, ParamDTO param) {
		boolean isSuccess = false;
		try {

			CallableStatement cstmt = cn.prepareCall("{call " + storeName
					+ "(?)}");

			// gán tham số cho store
			cstmt.setInt(param.getTenThamSo(), (int) param.getGiaTri());

			// thực thi câu truy vấn
			int iSS = cstmt.executeUpdate();
			if (iSS == 1) {
				isSuccess = true;
			}
		} catch (Exception ex) {
		}
		return isSuccess;
	}

	/**
	 * Thực thi câu truy vấn tìm kiếm
	 * 
	 * @param sql
	 *            câu truy vấn
	 * @return
	 */
	public ResultSet Search(String sql) {
		ResultSet data = null;
		try {
			Statement tm = this.cn.createStatement();
			data = tm.executeQuery(sql);

		} catch (Exception ex) {
		}
		return data;
	}
}
